﻿using System;
using System.Runtime.InteropServices;

namespace Equinoxe.NFC.EasyACR122
{
    class acr122
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct ACR122_LED_CONTROL
        {
            public long finalState;
            public bool updateEnabled;
            public long initialBlinkingState;
            public bool blinkEnabled;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct ACR122_TIMEOUTS
        {
            public UInt32 statusTimeout;
            public UInt32 numStatusRetries;
            public UInt32 responseTimeout;
            public UInt32 numResponseRetries;
        }

        //LED States
        public const int ACR122_LED_STATE_OFF = 0;
        public const int ACR122_LED_STATE_ON = 1;

        //Buzzer Mode
        public const byte ACR122_BUZZER_MODE_OFF = 0x00;
        public const byte ACR122_BUZZER_MODE_T1 = 0x01;
        public const byte ACR122_BUZZER_MODE_T2 = 0x02;

        //Error Codes
        public const long ACR122_ERROR_NO_MORE_HANDLES = 0x20000001;
        public const long ACR122_ERROR_UNKNOWN_STATUS = 0x20000002;
        public const long ACR122_ERROR_OPERATION_FAILURE = 0x20000003;
        public const long ACR122_ERROR_OPERATION_TIMEOUT = 0x20000004;
        public const long ACR122_ERROR_INVALID_CHECKSUM = 0x20000005;
        public const long ACR122_ERROR_INVALID_PARAMETER = 0x20000006;

        //====================================================
        //FUNCTIONS
        //====================================================

        #region

        public static int ACR122_OpenA(string portName, ref int phReader)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_OpenA(portName, ref phReader);
            }
            return acr122x86.ACR122_OpenA(portName, ref phReader);
        }

        public static int ACR122_OpenW(string portName, ref int phReader)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_OpenW(portName, ref phReader);
            }
            return acr122x86.ACR122_OpenW(portName, ref phReader);
        }
        public static int ACR122_GetFirmwareVersion(int phReader, int slotNum, byte[] firmwareVersion,
                                                           ref int pFirmwareVersion)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_GetFirmwareVersion(phReader, slotNum, firmwareVersion, ref pFirmwareVersion);
            }
            return acr122x86.ACR122_GetFirmwareVersion(phReader, slotNum, firmwareVersion, ref pFirmwareVersion);
        }
        public static int ACR122_Close(int phReader)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_Close(phReader);
            }
            return acr122x86.ACR122_Close(phReader);
        }
        public static int ACR122_DirectTransmit(int phReader, byte[] SendBuff, int SendBuffLen, byte[] RecvBuff,
                                                       ref int RecvBuffLen)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_DirectTransmit(phReader, SendBuff, SendBuffLen, RecvBuff, ref RecvBuffLen);
            }
            return acr122x86.ACR122_DirectTransmit(phReader, SendBuff, SendBuffLen, RecvBuff, ref RecvBuffLen);
        }
        public static int ACR122_GetNumSlots(int phReader, ref int pNumSlots)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_GetNumSlots(phReader, ref pNumSlots);
            }
            return acr122x86.ACR122_GetNumSlots(phReader, ref pNumSlots);
        }
        public static int ACR122_GetBaudRate(int phReader, ref int pBaudRate)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_GetBaudRate(phReader, ref pBaudRate);
            }
            return acr122x86.ACR122_GetBaudRate(phReader, ref pBaudRate);
        }
        public static int ACR122_SetBaudRate(int phReader, int baudRate)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_SetBaudRate(phReader, baudRate);
            }
            return acr122x86.ACR122_SetBaudRate(phReader, baudRate);
        }
        public static int ACR122_GetTimeouts(int phReader, ref ACR122_TIMEOUTS pTimeouts)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_GetTimeouts(phReader, ref pTimeouts);
            }
            return acr122x86.ACR122_GetTimeouts(phReader, ref pTimeouts);
        }
        public static int ACR122_SetTimeouts(int phReader, ref ACR122_TIMEOUTS pTimeouts)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_SetTimeouts(phReader, ref pTimeouts);
            }
            return acr122x86.ACR122_SetTimeouts(phReader, ref pTimeouts);
        }
        public static int ACR122_SetLedStatesWithBeep(int phReader, ref ACR122_LED_CONTROL[] controls,
                                                             int numControls, int t1, int t2, int numTimes,
                                                             int buzzerMode)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_SetLedStatesWithBeep(phReader, ref controls, numControls, t1, t2, numTimes, buzzerMode);
            }
            return acr122x86.ACR122_SetLedStatesWithBeep(phReader, ref controls, numControls, t1, t2, numTimes, buzzerMode);
        }
        public static int ACR122_PowerOnIcc(int phReader, int slotNum, ref byte atr, ref int pAtrLen)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_PowerOnIcc(phReader, slotNum, ref atr, ref pAtrLen);
            }
            return acr122x86.ACR122_PowerOnIcc(phReader, slotNum, ref atr, ref pAtrLen);
        }
        public static int ACR122_PowerOffIcc(int phReader, int slotNum)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_PowerOffIcc(phReader, slotNum);
            }
            return acr122x86.ACR122_PowerOffIcc(phReader, slotNum);
        }
        public static int ACR122_ExchangeApdu(int phReader, int slotNum, ref byte SendBuff, int SendBuffLen,
                                                     ref byte RecvBuff, ref int RecvBuffLen)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_ExchangeApdu(phReader, slotNum, ref SendBuff, SendBuffLen, ref RecvBuff, ref RecvBuffLen);
            }
            return acr122x86.ACR122_ExchangeApdu(phReader, slotNum, ref SendBuff, SendBuffLen, ref RecvBuff, ref RecvBuffLen);
        }
        public static int ACR122_PowerOnIcc(int phReader, int slotNum, byte[] atr, ref int pAtrLen)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_PowerOnIcc(phReader, slotNum, atr, ref pAtrLen);
            }
            return acr122x86.ACR122_PowerOnIcc(phReader, slotNum, atr, ref pAtrLen);
        }
        public static int ACR122_ExchangeApdu(int phReader, int slotNum, byte[] SendBuff, int SendBuffLen,
                                                     byte[] RecvBuff, ref int RecvBuffLen)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_ExchangeApdu(phReader, slotNum, SendBuff, SendBuffLen, RecvBuff, ref RecvBuffLen);
            }
            return acr122x86.ACR122_ExchangeApdu(phReader, slotNum, SendBuff, SendBuffLen, RecvBuff, ref RecvBuffLen);
        }
        public static int ACR122_SetLedStates(int phReader, int[] states, int numstates)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_SetLedStates(phReader, states, numstates);
            }
            return acr122x86.ACR122_SetLedStates(phReader, states, numstates);
        }
        public static int ACR122_DisplayLcdMessageA(int phReader, int row, int col, string message)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_DisplayLcdMessageA(phReader, row, col, message);
            }
            return acr122x86.ACR122_DisplayLcdMessageA(phReader, row, col, message);
        }
        public static int ACR122_DisplayLcdMessageExA(int phReader, int row, int col, int tableIndex,
                                                             int boldMode, string message)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_DisplayLcdMessageExA(phReader, row, col, tableIndex, boldMode, message);
            }
            return acr122x86.ACR122_DisplayLcdMessageExA(phReader, row, col, tableIndex, boldMode, message);
        }
        public static int ACR122_DisplayLcdMessageGBA(int phReader, int row, int col, int boldMode,
                                                             string message)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_DisplayLcdMessageGBA(phReader, row, col, boldMode, message);
            }
            return acr122x86.ACR122_DisplayLcdMessageGBA(phReader, row, col, boldMode, message);
        }
        public static int ACR122_ClearLcd(int phReader)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_ClearLcd(phReader);
            }
            return acr122x86.ACR122_ClearLcd(phReader);
        }
        public static int ACR122_EnableLcdBacklight(int phReader, bool enabled)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_EnableLcdBacklight(phReader, enabled);
            }
            return acr122x86.ACR122_EnableLcdBacklight(phReader, enabled);
        }
        public static int ACR122_EnableLed(int phReader, bool enabled)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_EnableLed(phReader, enabled);
            }
            return acr122x86.ACR122_EnableLed(phReader, enabled);
        }
        public static int ACR122_PauseLcdScrolling(int phReader)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_PauseLcdScrolling(phReader);
            }
            return acr122x86.ACR122_PauseLcdScrolling(phReader);
        }
        public static int ACR122_StopLcdScrolling(int phReader)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_StopLcdScrolling(phReader);
            }
            return acr122x86.ACR122_StopLcdScrolling(phReader);
        }
        public static int ACR122_SetLcdContrast(int phReader, int level)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_SetLcdContrast(phReader, level);
            }
            return acr122x86.ACR122_SetLcdContrast(phReader, level);
        }
        public static int ACR122_StartLcdScrolling(int phReader, int row, int col, int HRange, int VRange,
                                                          int Speed, int Direction)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_StartLcdScrolling(phReader, row, col, HRange, VRange, Speed, Direction);
            }
            return acr122x86.ACR122_StartLcdScrolling(phReader, row, col, HRange, VRange, Speed, Direction);
        }
        public static int ACR122_DrawLcd(int phReader, int lineIndex, byte[] pixelBuffer, int pixelBufferLen)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_DrawLcd(phReader, lineIndex, pixelBuffer, pixelBufferLen);
            }
            return acr122x86.ACR122_DrawLcd(phReader, lineIndex, pixelBuffer, pixelBufferLen);
        }
        public static int ACR122_Beep(int phReader, int buzzerOnDuration, int buzzerOffDuration, int numTimes)
        {
            if (Environment.Is64BitProcess)
            {
                return acr122x64.ACR122_Beep(phReader, buzzerOnDuration, buzzerOffDuration, numTimes);
            }
            return acr122x86.ACR122_Beep(phReader, buzzerOnDuration, buzzerOffDuration, numTimes);
        }
        #endregion




    }


}
